package us.icitap.commandcenter.ui.dispatcher;


import java.util.List;
import java.util.logging.Level;

import javax.jms.Connection;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;
import javax.jms.Session;

import org.vaadin.artur.icepush.ICEPush;

import us.icitap.commandcenter.CommandCenterUI;
import us.icitap.commandcenter.business.CallActionEnum;
import us.icitap.commandcenter.business.CallRolesEnum;
import us.icitap.commandcenter.business.ejb.persistence.Call;
import us.icitap.commandcenter.business.ejb.persistence.CallStatusEnum;
import us.icitap.commandcenter.business.ejb.persistence.Dispatcher;
import us.icitap.commandcenter.listeners.DispatcherListener;
import us.icitap.commandcenter.ui.custom.CustButton;
import us.icitap.commandcenter.ui.custom.CustVerticalLayout;
import us.icitap.commandcenter.ui.operator.CallForm;
import us.icitap.commandcenter.ui.shared.CallInfoWindow;
import us.icitap.commandcenter.ui.shared.GeneralVars;
import us.icitap.commandcenter.utils.HandleNotification;
import us.icitap.utils.Result;

import com.vaadin.event.Action;
import com.vaadin.server.ThemeResource;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Window;
import com.vaadin.ui.themes.Runo;

public class DispatcherVerticalLayout extends CustVerticalLayout implements DispatcherListener, MessageListener {

	private ICEPush pusher = new ICEPush();
	
	private Connection connection;
	private Session session;
	
	private List<Dispatcher> dispatchers;
	
	private NewCallTable newCallTable;
	private StartedVerificationTable startedVerificationTable;
	private ClosedVerificationTable closedVerificationTable;
	
	private StartVerificationWindow startVerificationWindow;
	private CloseVerificationWindow closeVerificationWindow;
	private UpdateVerificationWindow updateVerificationWindow;
	private ChangeDispatcherWindow changeDispatcherWindow;
	
	private UniqueNumberWindow uniqueNumberWindow;
	
	
	
    
	
    private final CustButton newCallButton = new CustButton();
    private  Window newCallWindow = null;
    
	public DispatcherVerticalLayout() {
//		this.setMargin(true);
		this.addStyleName("cust-margin-4");
		this.setWidth("900px");
		this.addExtension(pusher);
		final SelectDispatcherWindow window = new SelectDispatcherWindow(this);
		CommandCenterUI.getCurrent().addWindow(window);
		
		this.newCallButton.setIcon(new ThemeResource("img/icons/blue/Plus.png"));
		this.newCallButton.setStyleName(Runo.BUTTON_LINK);
		this.newCallButton.setDescription("<b>Hapet dritarja per te rregjistruar nje telefonate te re</b>");
		this.setSpacing(true);
		
	}
	

	public void startListening(){
	    try
	    {
	      connection = CommandCenterUI.appStatelessBean.getConnectionFactory().createConnection();
	      session= connection.createSession(false,Session.AUTO_ACKNOWLEDGE);

	      Destination dest;
	      for (Dispatcher dispatcher : this.dispatchers) {
			dest  = session.createTopic("DISP" + dispatcher.getId().toString());
			MessageConsumer mc = session.createConsumer(dest);
			mc.setMessageListener(this);
	      }

	      connection.start();

	    }
	    catch (JMSException e)
	    {
	      e.printStackTrace();
	    }
	   
	}

	public void setDispatchers(List<Dispatcher> dispatchers){
		this.dispatchers = dispatchers;
		
		final HorizontalLayout hl = new HorizontalLayout();

		
		this.newCallTable = new NewCallTable(this.dispatchers.size()==1);
		Result<List<Call>> result = CommandCenterUI.appStatelessBean.getInitialNewCallList(this.dispatchers);
		if(result.isSucceeded())
			this.newCallTable.addCallList(result.getObject());
		else
			HandleNotification.showErrorOnScreen(result.getMessage());
		
		
		hl.addComponent(this.newCallTable);
		
		
		hl.addComponent(this.newCallButton);
		hl.setComponentAlignment(this.newCallButton, Alignment.TOP_LEFT);
		
		this.addComponent(hl);
		
		this.startedVerificationTable = new StartedVerificationTable(this.dispatchers.size()==1);
		result = CommandCenterUI.appStatelessBean.getWvCallList(this.dispatchers);
		if(result.isSucceeded())
			this.startedVerificationTable.addCallList(result.getObject());
		else
			HandleNotification.showErrorOnScreen(result.getMessage());
		
		this.addComponent(this.startedVerificationTable);
		
		
		this.closedVerificationTable = new ClosedVerificationTable(this.dispatchers.size()==1);
		result = CommandCenterUI.appStatelessBean.getClosedCallList(this.dispatchers);
		if(result.isSucceeded())
			this.closedVerificationTable.addCallList(result.getObject());
		else
			HandleNotification.showErrorOnScreen(result.getMessage());
		
		this.addComponent(this.closedVerificationTable);

		this.newCallButton.addClickListener(new ClickListener() {
			
			@Override
			public void buttonClick(ClickEvent event) {
				DispatcherVerticalLayout.this.newCallWindow  = new Window("Rregjistrimi i nje telefonate te re");
				DispatcherVerticalLayout.this.newCallWindow.setResizable(false);
				DispatcherVerticalLayout.this.newCallWindow.center();
				DispatcherVerticalLayout.this.newCallWindow.setModal(true);
				CallForm callForm = new CallForm(DispatcherVerticalLayout.this, DispatcherVerticalLayout.this.getDispatchers());
				DispatcherVerticalLayout.this.newCallWindow.setContent(callForm);
				
				CommandCenterUI.getCurrent().removeWindow(DispatcherVerticalLayout.this.newCallWindow);
				CommandCenterUI.getCurrent().addWindow(DispatcherVerticalLayout.this.newCallWindow);
				
				
			}
		});
				
		newCallTable.addActionHandler(new Action.Handler() {
            public Action[] getActions(Object target, Object sender) {
               if(target == null) return null;
               return new Action[]{GeneralVars.START_VERIF,GeneralVars.SHOW_CALL_INFO };
               
            }
            
            public void handleAction(Action action, Object sender, Object target) {
            	Call call = (Call) target;
            	
            	if (GeneralVars.START_VERIF == action) {
            		if(startVerificationWindow == null) 
						startVerificationWindow = new StartVerificationWindow(DispatcherVerticalLayout.this, call);
					else
						startVerificationWindow.setCall(call);
					CommandCenterUI.getCurrent().removeWindow(startVerificationWindow);
					CommandCenterUI.getCurrent().addWindow(startVerificationWindow);
                }
            	else if (GeneralVars.SHOW_CALL_INFO == action) {
            		CallInfoWindow ciW = new CallInfoWindow(call,newCallTable);
                	ciW.show();
            	}
                
        }});
		
		startedVerificationTable.addActionHandler(new Action.Handler() {
            public Action[] getActions(Object target, Object sender) {
               if(target == null) return null;
               return new Action[]{GeneralVars.ADD_INFO,GeneralVars.CHANGE_DISPATCHER ,GeneralVars.CLOSE_CALL,GeneralVars.SHOW_CALL_INFO};
               
            }
            
            public void handleAction(Action action, Object sender, Object target) {
            	Call call = (Call) target;
            	
            	if (GeneralVars.ADD_INFO == action) {
            		if(updateVerificationWindow == null) 
            			updateVerificationWindow = new UpdateVerificationWindow(DispatcherVerticalLayout.this, call);
					else
						updateVerificationWindow.setCall(call);
            		CommandCenterUI.getCurrent().removeWindow(updateVerificationWindow);
					CommandCenterUI.getCurrent().addWindow(updateVerificationWindow);
                }
            	else if (GeneralVars.CHANGE_DISPATCHER == action) {
            		if(changeDispatcherWindow == null) 
            			changeDispatcherWindow = new ChangeDispatcherWindow( call, DispatcherVerticalLayout.this);
					else
						changeDispatcherWindow.setCall(call);
            		CommandCenterUI.getCurrent().removeWindow(changeDispatcherWindow);
					CommandCenterUI.getCurrent().addWindow(changeDispatcherWindow);
            	}
                else if (GeneralVars.CLOSE_CALL == action) {
                	if(closeVerificationWindow == null) 
						closeVerificationWindow = new CloseVerificationWindow(DispatcherVerticalLayout.this, call);
					else
						closeVerificationWindow.setCall(call);
                	CommandCenterUI.getCurrent().removeWindow(closeVerificationWindow);
					CommandCenterUI.getCurrent().addWindow(closeVerificationWindow);
                }
                else if (GeneralVars.SHOW_CALL_INFO == action) {
                	CallInfoWindow ciW = new CallInfoWindow(call,startedVerificationTable);
                	ciW.show();
    				
            	}

        }});
			
		closedVerificationTable.addActionHandler(new Action.Handler() {
			
			@Override
			public void handleAction(Action action, Object sender, Object target) {
				Call call = (Call) target;
				if(GeneralVars.CREATE_UN == action){
					if(call.getUniqueNumber() != null){
						HandleNotification.showInfoOnTray("Numri unik eshte i krijuar");
						return;
					}
						
					if(uniqueNumberWindow == null)
						uniqueNumberWindow = new UniqueNumberWindow(DispatcherVerticalLayout.this, call);
					else
						uniqueNumberWindow.setCall(call);
					
					CommandCenterUI.getCurrent().addWindow(uniqueNumberWindow);
				}
				 else if (GeneralVars.SHOW_CALL_INFO == action) {
	                	CallInfoWindow ciW = new CallInfoWindow(call,startedVerificationTable);
	                	ciW.show();
	    				
	            	}
				
				
			}
			
			@Override
			public Action[] getActions(Object target, Object sender) {
				 if(target == null) return null;
	               return new Action[]{GeneralVars.CREATE_UN,GeneralVars.SHOW_CALL_INFO};
			}
		});
		
		String dispatcherNames = "";
		
		for (Dispatcher dispatcher : dispatchers) {
			dispatcherNames += ", " + dispatcher.getName();
		}
		dispatcherNames = dispatcherNames.replaceFirst(",", "");
		
		if(this.getParent() != null) 
			this.getParent().setCaption(this.getParent().getCaption() + " - " + dispatcherNames);
			
		this.startListening();
	}

	@Override
	public void startCallVerification(Call call) {
		Result<Call> result = CommandCenterUI.appStatelessBean.startVerification(call);
		if(result.isSucceeded()){
			newCallTable.removeCall(call);
			startedVerificationTable.addCall(call);
			this.startVerificationWindow.close();
			HandleNotification.showInfoOnTray("Telefonata eshte ne pritje te verifikimit");
		}
		else {
			HandleNotification.showErrorOnScreen(result.getMessage());
		}

	}


	@Override
	public void updateCallInformation(Call call) {
		Result<Call> result = CommandCenterUI.appStatelessBean.updateCallInformation(call, CallRolesEnum.DISPATCHER);
		if(result.isSucceeded()){
			startedVerificationTable.updateCall(result.getObject());
			this.updateVerificationWindow.close();
			HandleNotification.showInfoOnTray("Telefonata vazhdon te verifikohet");
		}
		else
			HandleNotification.showErrorOnScreen(result.getMessage());
	}


	@Override
	public void closeCallVerification(Call call) {
		Result<Call> result = CommandCenterUI.appStatelessBean.closeVerification(call,CallRolesEnum.DISPATCHER);
		if(result.isSucceeded()){
			startedVerificationTable.removeCall(call);
			closedVerificationTable.addCall(call);
			this.closeVerificationWindow.close();
			HandleNotification.showInfoOnTray("Verifikimi i telefonates perfundoi");
		}
		else
			HandleNotification.showErrorOnScreen(result.getMessage());
	}

	

	@Override
	public void generateUniqueNumber(Call call) {
		Result<Call> result = CommandCenterUI.appStatelessBean.generateUniqueNumber(call);
		if(result.isSucceeded()){
			closedVerificationTable.updateCall(call);
			this.uniqueNumberWindow.close();	
		}
		else
			HandleNotification.showErrorOnScreen(result.getMessage());
	}


	@Override
	public void addNewCall(Call call) {
		if(call.isOfficerCall()) call.setActualStatus(CallStatusEnum.WV);
		
		Result<Call> result = CommandCenterUI.appStatelessBean.addNewCall(call,CallRolesEnum.DISPATCHER);
		if(result.isSucceeded()){
			if(call.isOfficerCall()){
				startedVerificationTable.addCall(result.getObject());
			}
			else{
				newCallTable.addCall(result.getObject());
			}
			
			this.newCallWindow.close();
		}
		else
			CommandCenterUI.LOG.logp(Level.SEVERE, "CallForm", "actYes", result.getMessage());	
	}

	
	@Override
	public void detach() {
		CommandCenterUI.LOG.info("DispatcherVerticalLayout.detach()");
		try {
			if(session != null) session.close();
		    if(connection != null) connection.close();
		} catch (JMSException e) {
			e.printStackTrace();
		}
		super.detach();
	}
	
	
	private boolean isCallForYou(Call call){
		for (Dispatcher d : this.dispatchers) {
			if(d.equals(call.getMainDispatcher())) return true;
		}
		return false;
				
	}
	@Override
	public void onMessage(Message message) {
		ObjectMessage objectMessage = (ObjectMessage)message;
		try {
			
			CallMessage callMessage  = (CallMessage) objectMessage.getObject();
			Call call = callMessage.getCall();
			
			if(CallActionEnum.NEW_CALL.equals(callMessage.getCallActionEnum())){
				newCallTable.addCall(callMessage.getCall());
				HandleNotification.showInfoOnTray("Erdhi nje telefonate e re");
	
			}
			else if (CallActionEnum.UPDATE_CALL.equals(callMessage.getCallActionEnum())){
				
				if(CallStatusEnum.N.equals(call.getActualStatus())){
					newCallTable.updateCall(call);
					HandleNotification.showInfoOnTray("U ndryshuan te dhenat e telefonates");
				}
				else{
					startedVerificationTable.updateCall(call);
					HandleNotification.showInfoOnTray("U ndryshuan te dhenat e telefonates");
				}	
			}
			else if(CallActionEnum.CHANGE_DISPATCHER.equals(callMessage.getCallActionEnum())){
				if(CallStatusEnum.N.equals(call.getActualStatus())){
					newCallTable.addCall(call);
					HandleNotification.showInfoOnTray("Erdhi nje telefonate e re");
				}
				else{
					startedVerificationTable.addCall(call);
					HandleNotification.showInfoOnTray("Erdhi nje telefonate e re me status 'duke u verifikuar'");
				}
			}
			else if(CallActionEnum.REMOVE_CALL.equals(callMessage.getCallActionEnum())){
				if(CallStatusEnum.N.equals(call.getActualStatus())){
					newCallTable.removeCall(call);
					HandleNotification.showInfoOnTray("Telefonata u hoq nga lista juaj");
				}
				else{
					startedVerificationTable.removeCall(call);
					HandleNotification.showInfoOnTray("Telefonata u hoq nga lista juaj");
				}
			}
			if(pusher.getUI() == null)
				this.addExtension(pusher);
			pusher.push();
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}


	@Override
	public void changeDispatcher(Call call) {
		Result<Call> result = CommandCenterUI.appStatelessBean.changeDispatcher(call, CallRolesEnum.DISPATCHER);
		if(result.isSucceeded()){
			changeDispatcherWindow.close();
			HandleNotification.showInfoOnTray("Telefonates iu ndryshua zona e mbulimit");
			
		}
		else
			HandleNotification.showErrorOnScreen(result.getMessage());
		
	}


	public List<Dispatcher> getDispatchers() {
		return dispatchers;
	}


	@Override
	public void addNewCallRelated(Call call) {
		// TODO Auto-generated method stub
		
	}
	
}
